package com.supermap.fabricsdk;

import org.hyperledger.fabric.sdk.Enrollment;
import org.hyperledger.fabric.sdk.HFClient;
import org.hyperledger.fabric.sdk.NetworkConfig;
import org.hyperledger.fabric.sdk.User;
import org.hyperledger.fabric.sdk.helper.Config;
import org.hyperledger.fabric.sdk.security.CryptoSuite;
import org.hyperledger.fabric.sdk.security.CryptoSuiteFactory;
import org.hyperledger.fabric_ca.sdk.Attribute;
import org.hyperledger.fabric_ca.sdk.HFCAClient;
import org.hyperledger.fabric_ca.sdk.RegistrationRequest;
import org.hyperledger.fabric_ca.sdk.exception.EnrollmentException;
import org.hyperledger.fabric_ca.sdk.exception.GenerateCRLException;
import org.hyperledger.fabric_ca.sdk.exception.InvalidArgumentException;
import org.hyperledger.fabric_ca.sdk.exception.RevocationException;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

/**
 * Supermap CA 接口实现类
 */
class SmCAImp implements SmCA {
    private HFCAClient hfcaClient = null;
    private User admin = null;

    SmCAImp(File networkConfigFile, String OrgName) {
        try {
            String cryptSuite = SmChain.getCryptSuite(networkConfigFile);
//            cryptSuite = "SHA256WITHECDSA";
            if (cryptSuite.equals("SM3WITHSM2")) {
                NetworkConfig networkConfig = NetworkConfig.fromYamlFile(networkConfigFile, true);
                // 设置国密加密套件
                Properties gmpropsIn = new Properties();
                gmpropsIn.setProperty(Config.HASH_ALGORITHM, "SM3");  // hash算法
                gmpropsIn.setProperty(Config.SIGNATURE_ALGORITHM, "SM3WITHSM2"); // 算法  对应   -> SHA256withECDSA
                CryptoSuite gmCrypto = CryptoSuiteFactory.getDefault().getCryptoSuite(gmpropsIn);
                hfcaClient = HFCAClient.createNewInstance(networkConfig.getOrganizationInfo(OrgName).getCertificateAuthorities().get(0));
                hfcaClient.setCryptoSuite(gmCrypto);
            } else if (cryptSuite.equals("SHA256WITHECDSA")) {
                NetworkConfig networkConfig = NetworkConfig.fromYamlFile(networkConfigFile);
                hfcaClient = HFCAClient.createNewInstance(networkConfig.getOrganizationInfo(OrgName).getCertificateAuthorities().get(0));
                admin = networkConfig.getPeerAdmin(OrgName);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public String register(SmUser user, SmUser adminUser, List<Attribute> attributeList) throws Exception {
        RegistrationRequest registrationRequest = new RegistrationRequest(user.getName());
        if (null != user.getEnrollSecret()) {
            registrationRequest.setSecret(user.getEnrollSecret());
            for (int i = 0; i < attributeList.size(); i++) {
                registrationRequest.addAttribute(attributeList.get(i));
            }
        }
        String secret = hfcaClient.register(registrationRequest, adminUser);
        return secret;
    }

    @Override
    public Enrollment enroll(String userName, String secret) throws EnrollmentException, InvalidArgumentException {
        Enrollment enrollment = hfcaClient.enroll(userName, secret);
        enrollment.getKey().toString();
        return enrollment;
    }

    @Override
    public Enrollment reenroll(SmUser user) throws EnrollmentException, InvalidArgumentException {
//        return hfcaClient.reenroll(user, req);
        return null;
    }

    /**
     * 如果 genCRL = true 则返回证书撤销列表，为 false 则不返回
     * @param userName 用户名
     * @param reason 注销原因
     * @param adminUser 管理员用户
     * @return
     * @throws InvalidArgumentException
     * @throws RevocationException
     */
    @Override
    public String revoke(String userName, String reason, SmUser adminUser, boolean b) throws InvalidArgumentException, RevocationException {
        return hfcaClient.revoke(adminUser, userName, reason, b);
    }

    @Override
    public String revoke(Enrollment enrollment, String reason, SmUser adminUser) throws InvalidArgumentException, RevocationException {
//        String result = hfcaClient.revoke(adminUser, smEnrollment, reason, true);
//        return result;
        return null;
    }

    @Override
    public String getCRL(User adminUser, Date revokedBefore, Date revokedAfter, Date expireBefore, Date expireAfter) throws GenerateCRLException, InvalidArgumentException {
        return hfcaClient.generateCRL(adminUser, revokedBefore, revokedAfter, expireBefore, expireAfter);
    }
}
